﻿using log4net;
using Mangox.BLL.Applet;
using Mangox.BLL.Stock;
using Mangox.Common;
using Mangox.Model.MyBusinessDB;
using Mangox.Model.Stock;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Reflection;
using System.Security.Cryptography;
using System.Web.Http;
using static Mangox.Model.Common.EnumComm;

namespace MGXAPI.Controllers.API
{
    /// <summary>
    /// 微信小程序用户授权
    /// UNIONID（多公众号统一id）
    /// </summary>
    public class UserWeChatController : ApiController
    {
        protected static ILog log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
        protected static string className = (new StackTrace()).GetFrame(1).GetMethod().ReflectedType.Name + "/";       //获取类名 
        private static string api_weixin = "https://api.weixin.qq.com/sns/jscode2session?appid=wx0530edd67b0ccd45&secret=d34df855f0080782f838cee8d273e065&js_code={0}&grant_type=authorization_code";
        private string api_acctoken = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=wx0530edd67b0ccd45&secret=d34df855f0080782f838cee8d273e065";
        private string api_release = "https://api.weixin.qq.com/wxa/release?access_token={0}";  //生效小程序

        #region 调用微信接口登录

        /// <summary>
        /// 微信登陆返回Openid
        /// http://localhost:13772/api/UserWeChat/Login
        /// </summary>
        /// <param name="resCode">wx.login 获取的code</param>
        /// <returns></returns>
        [HttpGet]
        public string Login(string resCode = null)
        {
            //resCode = "0239k7uy0j91hh1BIWry0kifuy09k7uu";//test

            log.InfoFormat(className + "Login signature-{0}", resCode);
            string openid = null;
            JsonRequest request = new JsonRequest();
            string url = string.Format(api_weixin, resCode);
            string result = null;
            try
            {
                result = request.Get(url);
                log.InfoFormat(className + "Login result-{0}", result);

                var model = JsonCommon.JsonToMode<WxLoginParam>(result);
                UserBLL bll = new UserBLL();

                //判断是登陆过，是否是新用户
                if (model == null || string.IsNullOrEmpty(model.openid))
                {
                    return null;
                }

                openid = model.openid;
                //如果是新用户记录到用户表
                var user = bll.GetUser(model.openid);
                bool flag = false;
                if (user == null)
                {
                    log.InfoFormat("未查询到用户，开始写入");
                    flag = bll.AddUser(model);
                    log.InfoFormat(className + "Login 用户登陆-{0}，Openid-{1}", flag, model.openid);
                }
                else
                {
                    flag = bll.UpdateUser(model);
                    log.InfoFormat(className + "Login 更新用户信息-{0}，Openid-{1}", flag, model.openid);
                }

                //每次使用记录到用户活跃表
                var f = new UWPDeviceBLL().AddUserActive(new UserActive() { Source = SourceType.applet.ToString(), IsFirst = 1, Openid = openid });
                if (!f)
                    log.InfoFormat("AddUserActive fail");
            }
            catch (Exception ex)
            {
                log.ErrorFormat(className + "Login url-{0}，result-{1}，Fail-{2}", url, result, ex.ToString());
                //StockCommBLL.SendEmail("系统异常", "StockBLL/GetZdt", logInfo);
            }

            return openid;

            //返回Json，灵活但是每个都要写
            //return new System.Net.Http.HttpResponseMessage()
            //{
            //    Content = new System.Net.Http.StringContent(result, System.Text.Encoding.UTF8, "application/json"),
            //};
        }


        /// <summary>
        /// 微信点击授权
        /// 参数对象用Post
        /// </summary>
        /// <param name="resCode"></param>
        /// <returns></returns>
        [HttpPost]
        public User Auth_wx(WxAuthParam param)
        {
            log.InfoFormat(className + "Auth_wx param-{0}", JsonCommon.ToJson<WxAuthParam>(param));
            try
            {
                UserBLL bll = new UserBLL();
                return bll.UpdateAuthUser(param);

            }
            catch (Exception ex)
            {
                log.ErrorFormat(className + "Auth_wx Fail-{0}", ex.ToString());
            }
            return null;
        }

        /// <summary>
        /// 获取用户信息
        /// </summary>
        /// <param name="openid"></param>
        /// <returns></returns>
        [HttpGet]
        public User GetUser(string openid)
        {
            log.InfoFormat(className + "GetUser openid-{0}", openid);
            try
            {
                UserBLL bll = new UserBLL();
                return bll.GetUser(openid);
            }
            catch (Exception ex)
            {
                log.ErrorFormat(className + "GetUser Fail-{0}", ex.ToString());
            }
            return null;
        }


        [HttpGet]
        public string GetAccess_token(string openid = null)
        {
            log.InfoFormat(className + "GetAccess_token start");
            string access_token = null;
            JsonRequest request = new JsonRequest();
            string url = string.Format(api_acctoken);
            string result = null;
            try
            {
                result = request.Get(url);
                log.InfoFormat(className + "GetAccess_token result-{0}", result);

                var model = JsonCommon.JsonToMode<WxAccTokenResult>(result);
                access_token = model.access_token;
            }
            catch (Exception ex)
            {
                log.ErrorFormat(className + "GetAccess_token result-{0}，Fail-{1}", result, ex.ToString());
            }

            return access_token;
        }

        /// <summary>
        /// 发布后小程序未生效调用
        /// </summary>
        /// <param name="access_token"></param>
        /// <returns></returns>
        [HttpGet]
        public string Release()
        {
            log.InfoFormat(className + "Release start");

            string access_token = GetAccess_token();
            JsonRequest request = new JsonRequest();
            string url = string.Format(api_release);
            string result = null;
            try
            {
                result = request.Get(url);
                log.InfoFormat(className + "Release access_token-{0}，result-{1}", access_token, result);
            }
            catch (Exception ex)
            {
                log.ErrorFormat(className + "Release access_token-{0}，result-{1}, fail-{2}", access_token, result, ex);
            }
            return result;
        }

        //encryptedData 解密后为以下 json 结构，详见加密数据解密算法
        //{
        //    "openId": "OPENID",
        //    "nickName": "NICKNAME",
        //    "gender": GENDER,
        //    "city": "CITY",
        //    "province": "PROVINCE",
        //    "country": "COUNTRY",
        //    "avatarUrl": "AVATARURL",
        //    "unionId": "UNIONID",
        //    "watermark":
        //    {
        //        "appid":"APPID",
        //    "timestamp":TIMESTAMP
        //    }
        //}

        /// <summary>
        /// C#/.net微信小程序encryptedData解密
        /// 获取以上参数
        /// getUserInfo: function (e)
        /// 有敏感信息：{"type":"getuserinfo","timeStamp":2394,"target":{"id":"","offsetLeft":110,"offsetTop":21,"dataset":{}},"currentTarget":{"id":"","offsetLeft":110,"offsetTop":21,"dataset":{}},"detail":{"errMsg":"getUserInfo:ok","rawData":"{\"nickName\":\"李强\",\"gender\":1,\"language\":\"zh_CN\",\"city\":\"Shenzhen\",\"province\":\"Guangdong\",\"country\":\"China\",\"avatarUrl\":\"https://wx.qlogo.cn/mmopen/vi_32/sOOAOWxxX1wYEKvTusaicnDX9E8w7WES6nqGsLicy7zcx3WNyfazQiaVrFL76JQOnVpMRe5eyVP2HUrXJayX6c7lQ/132\"}","signature":"1800d1c2c37b710ddae74e92a3d0146f50f6260e","encryptedData":"DkIqConw/60+AAzH24bp4R/KQYi1wwX5TR9BSft6CIG81gXqho6nDTvqctMNDaAfd8r6rY46KwPPU10EKDuigin6fd0MQ/ZZylFzj3MfBbFXIw1AHC09yzziajGIJMdQ/kvzFV8t/liOAWzzs1RfYx90LglKq4qVHeoSEU1QAK6pqI9mfU0CeiUAW1tShigKhFSvlTpyx5e3v05hIJNnUm1KKGM0H26yDW6zUu77PUYErrNvS/LGZVGcRCya/a8SvCt6Yfc1oTnji14S4io04z9wuIcK9I67us/mgU3DyO/Y38mkqFfgO0gzUgus15pJvHNGJ+n79AzqBKai3bDMqro+ITS0iPwcTkTnT4w1H7K3lIn2oQxQGJzFBvfzNrcN8ILMceK1VUMCuXVAzp6cIABJm8bCRO/9ZhYFG5217CraAKGgCDbNgPClQupZOhyB1PdmDFu0uaIBA0V3uQbId3//Xb8v4zv9jE28UNNvoFg=","iv":"kjolroKTtcs/3p75Q89QJw==","userInfo":{"nickName":"李强","gender":1,"language":"zh_CN","city":"Shenzhen","province":"Guangdong","country":"China","avatarUrl":"https://wx.qlogo.cn/mmopen/vi_32/sOOAOWxxX1wYEKvTusaicnDX9E8w7WES6nqGsLicy7zcx3WNyfazQiaVrFL76JQOnVpMRe5eyVP2HUrXJayX6c7lQ/132"}}}
        /// </summary>
        /// <param name="encryptedDataStr"></param>
        /// <param name="session_key">和openid一起，换取后的key</param>
        /// <param name="iv"></param>
        /// <returns></returns>
        public string AES_decrypt(string encryptedDataStr, string session_key, string iv)
        {
            RijndaelManaged rijalg = new RijndaelManaged();
            //-----------------    
            //设置 cipher 格式 AES-128-CBC    

            rijalg.KeySize = 128;

            rijalg.Padding = PaddingMode.PKCS7;
            rijalg.Mode = CipherMode.CBC;

            rijalg.Key = Convert.FromBase64String(session_key);
            rijalg.IV = Convert.FromBase64String(iv);

            byte[] encryptedData = Convert.FromBase64String(encryptedDataStr);
            //解密    
            ICryptoTransform decryptor = rijalg.CreateDecryptor(rijalg.Key, rijalg.IV);

            string result;
            using (MemoryStream msDecrypt = new MemoryStream(encryptedData))
            {
                using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
                {
                    using (StreamReader srDecrypt = new StreamReader(csDecrypt))
                    {

                        result = srDecrypt.ReadToEnd();
                    }
                }
            }
            return result;
        }

        #endregion

        /// <summary>
        /// http://localhost:13772/api/UserWeChat/test
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public string test()
        {
            return "test";
        }

    }
}
